import qiskit
import networkx as nx

import numpy as np
from qiskit_algorithms.optimizers import COBYLA
from qiskit.circuit.library import TwoLocal
from qiskit.quantum_info import SparsePauliOp
from qiskit_algorithms.minimum_eigensolvers import QAOA
from qiskit.primitives import StatevectorSampler, StatevectorEstimator

from qiskit import QuantumCircuit, transpile
from qiskit_algorithms import QAOA
from qiskit_algorithms.optimizers import COBYLA
from qiskit.primitives import Sampler
from qiskit.quantum_info import SparsePauliOp
from qiskit_aer import AerSimulator
import numpy as np

# 定义图的边（四节点的环图）
num_qubits = 10
edges = [(i, (i + 1) % num_qubits) for i in range(num_qubits)]

# 构造问题哈密顿量 H_C = Σ Z_i Z_j
hamiltonian = SparsePauliOp.from_sparse_list(
    [(["Z", "Z"], [i, j], 1.0) for i, j in edges],
    num_qubits=num_qubits
)

# 构造混合哈密顿量（ΣX_i）
# 混合哈密顿量通过施加横向磁场，使量子比特在计算基态之间产生叠加和跃迁，这种量子隧穿效应帮助算法跳出局部最优解，增强全局搜索能力。
mixer = SparsePauliOp.from_sparse_list(
    [(["X"], [i], 1.0) for i in range(num_qubits)],
    num_qubits=num_qubits
)

# 设置QAOA参数
p = 1  # QAOA层数
initial_point = np.random.uniform(0, 2 * np.pi, size=2 * p)
optimizer = COBYLA(maxiter=100)

# 初始化QAOA
qaoa = QAOA(
    sampler=Sampler(),
    optimizer=optimizer,
    reps=p,
    mixer=mixer,
    initial_point=initial_point,
)

# 运行QAOA求解最小本征值
result = qaoa.compute_minimum_eigenvalue(hamiltonian)

print("优化参数:", result.optimal_parameters)
print("最优期望值:", result.eigenvalue)

# 构建最优参数的量子电路
optimal_circuit = qaoa.ansatz.assign_parameters(result.optimal_parameters)


# 使用模拟器进行采样
simulator = AerSimulator()
compiled_circuit = transpile(optimal_circuit, simulator)
counts = simulator.run(compiled_circuit, shots=1000).result().get_counts()

# 输出测量结果
max_cut = max(counts, key=lambda k: counts[k])
print("\n最大切割方案:", max_cut)
print("切割边数:", sum(1 for (i, j) in edges if max_cut[-i-1] != max_cut[-j-1]))

# 解释：字符串是小端序，例如'0010'表示q0=0, q1=1, q2=0, q3=0
# 因此，max_cut[-i-1] 获取第i个量子位的值